//
// Created by l00391713 on 2024/2/29.
//
#include <chrono>
#include "gtest.h"
#include "StoreMessagePacker.hpp"

using namespace c10d::pta;

class StoreMessagePackerTest : public testing::Test {
protected:
    static void CommonTestForPackUnpack(const StoreMessage &originMessage, const std::string &testName) noexcept
    {
        auto buffer = StoreMessagePacker::Pack(originMessage);
        ASSERT_TRUE(StoreMessagePacker::Full(buffer)) << " for case " << testName;

        StoreMessage unpackedMessage;
        auto ret = StoreMessagePacker::Unpack(buffer, unpackedMessage);
        ASSERT_EQ(buffer.size(), static_cast<size_t>(ret)) << " for case " << testName;

        EXPECT_EQ(originMessage.mt, unpackedMessage.mt) << " for case " << testName;
        EXPECT_EQ(originMessage.keys, unpackedMessage.keys) << " for case " << testName;
        EXPECT_EQ(originMessage.values.size(), unpackedMessage.values.size()) << " for case " << testName;
        for (auto i = 0U; i < originMessage.values.size(); i++) {
            EXPECT_EQ(originMessage.values[i], unpackedMessage.values[i]) << " for case " << testName <<
                "value index: " << i;
        }
    }
};

TEST_F(StoreMessagePackerTest, set_request)
{
    std::string value{ "3713481341" };
    StoreMessage message{ MessageType::SET, "this_is_test_key_set",
        std::vector<uint8_t>{ value.begin(), value.end() } };

    CommonTestForPackUnpack(message, "set_request");
}

TEST_F(StoreMessagePackerTest, compare_and_set_request)
{
    std::string expect{ "123456" };
    std::string set{ "654321" };
    StoreMessage message{ MessageType::COMPARE_SET, "this_is_test_key_compare_and_set",
        std::vector<uint8_t>{ expect.begin(), expect.end() }, std::vector<uint8_t>{ set.begin(), set.end() } };

    CommonTestForPackUnpack(message, "compare_and_set_request");
}

TEST_F(StoreMessagePackerTest, get_request)
{
    StoreMessage message{ MessageType::GET, "this_is_test_key_get" };

    CommonTestForPackUnpack(message, "get_request");
}

TEST_F(StoreMessagePackerTest, add_request)
{
    std::string value{ "8786" };
    StoreMessage message{ MessageType::ADD, "this_is_test_key_add",
        std::vector<uint8_t>{ value.begin(), value.end() } };

    CommonTestForPackUnpack(message, "add_request");
}

TEST_F(StoreMessagePackerTest, get_key_num_request)
{
    StoreMessage message{ MessageType::GET_NUM_KEYS };
    CommonTestForPackUnpack(message, "get_key_num_request");
}

TEST_F(StoreMessagePackerTest, del_key_request)
{
    StoreMessage message{ MessageType::DELETE_KEY, "this_is_test_key_del" };
    CommonTestForPackUnpack(message, "del_key_request");
}

TEST_F(StoreMessagePackerTest, wait_keys_request)
{
    std::chrono::milliseconds time(10000);
    std::vector<std::string> keys;
    for (auto i = 0; i < 100; i++) {
        keys.emplace_back(std::string("this is test key for ").append(std::to_string(i)));
    }

    StoreMessage message{ MessageType::WAIT, keys, time.count() };
    CommonTestForPackUnpack(message, "wait_keys_request");
}
